Summary

This short analysis explores the overlap between fishing and farming among surveyed households in Honduras. We start by quickly answering the core question for the entire dataset across all provinces and years: What percentage of fishers also engage in farming? We then outline the availability of household survey data by province and year. Following that, we examine the composition of household income sources at the national level, as well as disaggregated by province and by year. Finally, we analyze the extent to which fishing households also engage in farming, presenting results through a series of pie charts for the full sample, by province, and by year.

The raw dataset used for this analysis can be accessed here.


merged_hhs_hon <- merged_hhs %>% 
  filter(g1_country == "HND")


# Create a vector of the income percentage columns
income_cols <- c(
  "g4_hh_average_income_source_a_income_farming",
  "g4_hh_average_income_source_b_income_harvesting",
  "g4_hh_average_income_source_c_income_fishing_artisanal",
  "g4_hh_average_income_source_d_income_fishing_aquaculture",
  "g4_hh_average_income_source_e_income_buying_trading",
  "g4_hh_average_income_source_f_income_processing",
  "g4_hh_average_income_source_g_income_extraction",
  "g4_hh_average_income_source_h_income_tourism",
  "g4_hh_average_income_source_i_income_other_wage",
  "g4_hh_average_income_source_j_income_industrial",
  "g4_hh_average_income_source_k_income_other"
)

# Create a new dataframe with a total income contribution column
merged_hhs_hon_with_sum <- merged_hhs_hon %>%
  mutate(across(all_of(income_cols), ~ as.numeric(.))) %>%
  mutate(total_income_pct = rowSums(select(., all_of(income_cols)), na.rm = TRUE))


sum(merged_hhs_hon_with_sum$total_income_pct != 100) #Great: just 60 non 100 observations!
#> [1] 60

merged_hhs_hon_clean <- merged_hhs_hon_with_sum %>%
  filter(total_income_pct == 100)

# Keep and rename the specified columns
merged_hhs_hon_source <- merged_hhs_hon_clean %>%
  select(
    country = g1_country,
    year,
    province = merged_hhs_province,
    municipality = merged_hhs_municipality,
    community = merged_hhs_community,
    all_of(income_cols)
  )

# Add fisher and farmer flags
df_fisher_farming <- merged_hhs_hon_source %>%
  mutate(
    is_fisher = g4_hh_average_income_source_c_income_fishing_artisanal > 0 |
                g4_hh_average_income_source_j_income_industrial > 0,
    is_farmer = g4_hh_average_income_source_a_income_farming > 0
  )

# Total observations in the dataset
total_obs <- nrow(df_fisher_farming)

# Count total fishers and fishers who also farm
total_fishers <- sum(df_fisher_farming$is_fisher, na.rm = TRUE)
fishers_also_farmers <- sum(df_fisher_farming$is_fisher & df_fisher_farming$is_farmer, na.rm = TRUE)

# Percentages
fisher_share_of_sample <- total_fishers / total_obs * 100
farmers_among_fishers_pct <- fishers_also_farmers / total_fishers * 100


# write.csv(merged_hhs_hon_source, "hhs_honduras_clean.csv", row.names = FALSE)

total_fishers
#> [1] 1722
fishers_also_farmers
#> [1] 650
round(farmers_among_fishers_pct, 1)
#> [1] 37.7

Do Honduras Fishers Also Farm?

Short answer: Out of the 2,738 households surveyed in Honduras from 2019 to 2024, 1,722 were identified as fishers, representing 63% of the total sample. Among them, 650 households also reported income from farming activities—this means that 38% of fishers also farm.

Disaggregated Findings

There is substantial variation across provinces. For example, in Colón and Cortés, the proportion of fishers who also farm is around 40%, while in Islas de la Bahía, very few fishers report farming income. In contrast, almost all fishers in Atlántida also farm (For details, see section Fishing and Farming Households → Provincial Breakdown).

It’s important to note that the year-level disaggregation of results should be interpreted with caution. As shown in the summary table, different provinces were sampled in different years, making it difficult to distinguish year effects from geographic differences. The observed year-to-year patterns largely reflect changes in where data was collected, rather than temporal shifts in household activity (For details, see section Fishing and Farming Households → Yearly Breakdown).

Details and Assumptions

  • This analysis is based on responses to a survey question about the share of household income coming from different sources. Because of this, the data likely underestimates fishing or farming done solely for household consumption, as it only captures income-generating activities.

  • A household was classified as engaged in fishing if it reported any income from artisanal or industrial fishing. Similarly, a household was classified as engaged in farming if it reported income from agriculture or livestock activities. These classifications are intentionally inclusive: even a small income share from one of these activities was sufficient for a household to be included.


Available Data Overview

merged_hhs_hon_source %>%
  count(province, year) %>%
  pivot_wider(
    names_from = year,
    values_from = n,
    values_fill = 0
  ) %>%
  rename(Province = province) %>%
  select(Province, `2019`, `2021`, `2023`, `2024`) %>%
  kable("html", caption = "Number of Observations per Province per Year") %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = TRUE,
    position = "center"
  ) %>%
  column_spec(1, width = "160px")  # Only the first column wider
Number of Observations per Province per Year
Province 2019 2021 2023 2024
Atlántida 0 0 288 288
Colón 0 1122 275 0
Cortés 559 0 0 1
Islas de la Bahía 205 0 0 0

Income Composition by Source

National Overview

# Recode labels (example, adjust as needed)
income_labels <- c(
  "Farming",
  "Forest Harvesting",
  "Artisanal Fishing",
  "Aquaculture",
  "Fish Buying/Trading",
  "Fish Processing",
  "Marine Extraction",
  "Marine Tourism",
  "Other Wage Labor",
  "Industrial Fishing",
  "Other"
)

# Create the long-format dataset and summarize income proportions
df_income_long <- merged_hhs_hon_source %>%
  select(all_of(income_cols)) %>%
  mutate(across(everything(), as.numeric)) %>%
  filter(if_any(everything(), ~ !is.na(.))) %>%  # Keep rows with at least one value
  pivot_longer(everything(), names_to = "source", values_to = "income_pct") %>%
  mutate(source = recode(source, !!!setNames(income_labels, income_cols))) %>%
  group_by(source) %>%
  summarise(total_pct = sum(income_pct, na.rm = TRUE)) %>%
  mutate(prop = total_pct / sum(total_pct)) %>%
  arrange(desc(prop)) %>%
  mutate(
    source = factor(source, levels = source),
    label = paste0(source, " (", scales::percent(prop, accuracy = 1), ")")
  )

# Define colors
source_colors <- setNames(
  RColorBrewer::brewer.pal(n = nrow(df_income_long), name = "Paired"),
  df_income_long$source
)

# Define the color palette using RColorBrewer (or keep your custom colors)
source_colors <- setNames(
  RColorBrewer::brewer.pal(n = nrow(df_income_long), name = "Paired"),
  df_income_long$source
)

# Swap the colors
temp_color <- source_colors["Other"]
source_colors["Other"] <- source_colors["Industrial Fishing"]
source_colors["Industrial Fishing"] <- temp_color

temp_color2 <- source_colors["Other Wage Labor"]
source_colors["Other Wage Labor"] <- source_colors["Forest Harvesting"]
source_colors["Forest Harvesting"] <- temp_color2

# Create the plot
ggplot(df_income_long, aes(x = source, y = prop, fill = source)) +
  geom_col(width = 0.8) +
  geom_text(aes(label = scales::percent(prop, accuracy = 1)),
            vjust = -0.3, size = 3.5, color = "black") +
  scale_y_continuous(labels = scales::percent_format(), expand = expansion(mult = c(0, 0.1))) +
  scale_fill_manual(
    values = source_colors,
    labels = df_income_long$label
  ) +
  labs(
    title = "Total Income Share by Source",
    x = "Source",
    y = "Proportion of Reported Income Sources",
    fill = "Income Source"
  ) +
  theme_minimal() +
  theme(
    legend.position = "right",
    legend.title = element_text(face = "bold"),
    legend.text = element_text(size = 10),
    axis.text.x = element_text(angle = 45, hjust = 1)
  )

Provincial Breakdown

# Create long-format dataset with province included
df_income_long_province <- merged_hhs_hon_source %>%
  select(province, all_of(income_cols)) %>%
  mutate(across(all_of(income_cols), as.numeric)) %>%
  filter(if_any(all_of(income_cols), ~ !is.na(.))) %>%
  pivot_longer(cols = all_of(income_cols), names_to = "source", values_to = "income_pct") %>%
  mutate(source = recode(source, !!!setNames(income_labels, income_cols))) %>%
  group_by(province, source) %>%
  summarise(total_pct = sum(income_pct, na.rm = TRUE), .groups = "drop") %>%
  group_by(province) %>%
  mutate(prop = total_pct / sum(total_pct)) %>%
  arrange(province, desc(prop)) %>%
  mutate(source = factor(source, levels = income_labels))  # to keep source order consistent

province_sample_sizes <- merged_hhs_hon_source %>%
  count(province, name = "n")

df_income_long_province <- df_income_long_province %>%
  left_join(province_sample_sizes, by = "province") %>%
  mutate(province_label = paste0(province, " (n = ", n, ")"))

# Ensure factor levels match
df_income_long_province <- df_income_long_province %>%
  mutate(source = factor(source, levels = income_labels))

source_colors <- c(
  "Artisanal Fishing"    = "#A6CEE3", 
  "Other"                = "#FDBF6F",  
  "Farming"              = "#B2DF8A", 
  "Other Wage Labor"     = "#CAB2D6", 
  "Fish Buying/Trading"  = "#FB9A99", 
  "Fish Processing"      = "#E31A1C", 
  "Industrial Fishing"   = "#1F78B4", 
  "Aquaculture"          = "#FF7F00",  
  "Marine Tourism"       = "#6A3D9A",  
  "Forest Harvesting"    = "#33A02C", 
  "Marine Extraction"    = "#FFFF99"  
)

# Create the plot
ggplot(df_income_long_province, aes(x = source, y = prop, fill = source)) +
  geom_col(width = 0.8) +
  geom_text(aes(label = scales::percent(prop, accuracy = 1)),
            vjust = -0.3, size = 3, color = "black") +
  facet_wrap(~ province_label) +
  scale_y_continuous(labels = scales::percent_format(), expand = expansion(mult = c(0, 0.1))) +
  scale_fill_manual(values = source_colors)+
  labs(
    title = "Income Share by Source and Province",
    x = "Income Source",
    y = "Proportion of Total Reported Income",
    fill = "Income Source"
  ) +
  theme_minimal() +
  theme(
    legend.position = "bottom",
    legend.title = element_text(face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    strip.text = element_text(face = "bold"),
    panel.border = element_rect(color = "black", fill = NA, linewidth = 0.8)
  )

Yearly Breakdown

# Create long-format dataset with year included
df_income_long_year <- merged_hhs_hon_source %>%
  select(year, all_of(income_cols)) %>%
  mutate(across(all_of(income_cols), as.numeric)) %>%
  filter(if_any(all_of(income_cols), ~ !is.na(.))) %>%
  pivot_longer(cols = all_of(income_cols), names_to = "source", values_to = "income_pct") %>%
  mutate(source = recode(source, !!!setNames(income_labels, income_cols))) %>%
  group_by(year, source) %>%
  summarise(total_pct = sum(income_pct, na.rm = TRUE), .groups = "drop") %>%
  group_by(year) %>%
  mutate(prop = total_pct / sum(total_pct)) %>%
  arrange(year, desc(prop)) %>%
  mutate(source = factor(source, levels = income_labels))

# Get sample size by year
year_sample_sizes <- merged_hhs_hon_source %>%
  count(year, name = "n")

# Add year (n = ...) label
df_income_long_year <- df_income_long_year %>%
  left_join(year_sample_sizes, by = "year") %>%
  mutate(year_label = paste0("Year ", year, " (n = ", n, ")"))

# Ensure factor levels match again
df_income_long_year <- df_income_long_year %>%
  mutate(source = factor(source, levels = income_labels))

# Define consistent source colors manually
source_colors <- c(
  "Artisanal Fishing"    = "#A6CEE3", 
  "Other"                = "#FDBF6F",  
  "Farming"              = "#B2DF8A", 
  "Other Wage Labor"     = "#CAB2D6", 
  "Fish Buying/Trading"  = "#FB9A99", 
  "Fish Processing"      = "#E31A1C", 
  "Industrial Fishing"   = "#1F78B4", 
  "Aquaculture"          = "#FF7F00",  
  "Marine Tourism"       = "#6A3D9A",  
  "Forest Harvesting"    = "#33A02C", 
  "Marine Extraction"    = "#FFFF99"  
)

# Create the plot faceted by year
ggplot(df_income_long_year, aes(x = source, y = prop, fill = source)) +
  geom_col(width = 0.8) +
  geom_text(aes(label = scales::percent(prop, accuracy = 1)),
            vjust = -0.3, size = 3, color = "black") +
  facet_wrap(~ year_label) +
  scale_y_continuous(labels = scales::percent_format(), expand = expansion(mult = c(0, 0.1))) +
  scale_fill_manual(values = source_colors) +
  labs(
    title = "Income Share by Source and Year",
    x = "Income Source",
    y = "Proportion of Total Reported Income",
    fill = "Income Source"
  ) +
  theme_minimal() +
  theme(
    legend.position = "bottom",
    legend.title = element_text(face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    strip.text = element_text(face = "bold"),
    panel.border = element_rect(color = "black", fill = NA, linewidth = 0.8)
  )

Fishing and Farming Households

National Overview

# Define is_fisher and is_farmer up front
df_national <- merged_hhs_hon_source %>%
  mutate(
    is_fisher = if_else(
      coalesce(g4_hh_average_income_source_c_income_fishing_artisanal, 0) > 0 |
      coalesce(g4_hh_average_income_source_j_income_industrial, 0) > 0,
      TRUE, FALSE, missing = FALSE
    ),
    is_farmer = if_else(
      coalesce(g4_hh_average_income_source_a_income_farming, 0) > 0,
      TRUE, FALSE, missing = FALSE
    )
  )

# --- WHOLE POPULATION PIE ---
df_full <- df_national %>%
  mutate(
    group = if_else(is_fisher, "Fishers", "Non-Fishers")
  ) %>%
  count(group) %>%
  mutate(
    prop = n / sum(n),
    label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
  )

n_total <- sum(df_full$n)

pie1 <- ggplot(df_full, aes(x = "", y = prop, fill = group)) +
  geom_col(width = 1, color = "white") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 5) +
  scale_fill_manual(values = c("Fishers" = "#6baed6", "Non-Fishers" = "#fb6a4a")) +
  labs(title = paste0("Whole Population in Honduras (n = ", n_total, ")")) +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
    legend.position = "none"
  )

# --- FISHING POPULATION PIE ---
df_fishers <- df_national %>%
  filter(is_fisher) %>%
  mutate(
    group = if_else(is_farmer, "Fishers who also farm", "Fishers only")
  ) %>%
  count(group) %>%
  mutate(
    prop = n / sum(n),
    label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
  )

n_fishers <- sum(df_fishers$n)

pie2 <- ggplot(df_fishers, aes(x = "", y = prop, fill = group)) +
  geom_col(width = 1, color = "white") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 3.5) +
  scale_fill_manual(values = c("Fishers only" = "#6baed6", "Fishers who also farm" = "#B2DF8A")) +
  labs(title = paste0("Fishing Population (n = ", n_fishers, ")")) +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
    legend.position = "none"
  )

# --- Combine and display ---
ggdraw() +
  draw_plot(pie1, x = -0.2, y = 0, width = 1, height = 1) +         
  draw_plot(pie2, x = 0.44, y = 0.1, width = 0.6, height = 0.6)

Provincial Breakdown


# List of provinces
provinces <- unique(na.omit(merged_hhs_hon_source$province))

# Loop through each province and display plot
for (prov in provinces) {
  
  df_prov <- merged_hhs_hon_source %>%
    filter(province == prov) %>%
    mutate(
      is_fisher = if_else(
        coalesce(g4_hh_average_income_source_c_income_fishing_artisanal, 0) > 0 |
        coalesce(g4_hh_average_income_source_j_income_industrial, 0) > 0,
        TRUE, FALSE, missing = FALSE
      ),
      is_farmer = if_else(
        coalesce(g4_hh_average_income_source_a_income_farming, 0) > 0,
        TRUE, FALSE, missing = FALSE
      )
    )
  
  ## --- WHOLE POPULATION PIE ---
  df_full <- df_prov %>%
    mutate(
      group = if_else(is_fisher, "Fishers", "Non-Fishers")
    ) %>%
    count(group) %>%
    mutate(
      prop = n / sum(n),
      label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
    )

  n_total <- sum(df_full$n)

  pie1 <- ggplot(df_full, aes(x = "", y = prop, fill = group)) +
    geom_col(width = 1, color = "white") +
    coord_polar(theta = "y") +
    geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 5) +
    scale_fill_manual(values = c("Fishers" = "#6baed6", "Non-Fishers" = "#fb6a4a")) +
    labs(title = paste0("Whole Population in ", prov, " (n = ", n_total, ")")) +
    theme_void() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
      legend.position = "none"
    )
  
  ## --- FISHERS ONLY PIE ---
  df_fishers <- df_prov %>%
    filter(is_fisher) %>%
    mutate(
      group = if_else(is_farmer, "Fishers who also farm", "Fishers only")
    ) %>%
    count(group) %>%
    mutate(
      prop = n / sum(n),
      label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
    )

  n_fishers <- sum(df_fishers$n)

  pie2 <- ggplot(df_fishers, aes(x = "", y = prop, fill = group)) +
    geom_col(width = 1, color = "white") +
    coord_polar(theta = "y") +
    geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 4) +
    scale_fill_manual(values = c("Fishers only" = "#6baed6", "Fishers who also farm" = "#B2DF8A")) +
    labs(title = paste0("Fishing Population (n = ", n_fishers, ")")) +
    theme_void() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
      legend.position = "none"
    )

  # Combine and display
  final_plot <- cowplot::ggdraw() +
    draw_plot(pie1, x = -0.2, y = 0, width = 1, height = 1) +
    draw_plot(pie2, x = 0.44, y = 0.1, width = 0.6, height = 0.6)

  print(final_plot)
}

Yearly Breakdown

# List of years
years <- unique(na.omit(merged_hhs_hon_source$year))

# Loop through each year and display plot
for (yr in years) {
  
  df_year <- merged_hhs_hon_source %>%
    filter(year == yr) %>%
    mutate(
      is_fisher = if_else(
        coalesce(g4_hh_average_income_source_c_income_fishing_artisanal, 0) > 0 |
        coalesce(g4_hh_average_income_source_j_income_industrial, 0) > 0,
        TRUE, FALSE, missing = FALSE
      ),
      is_farmer = if_else(
        coalesce(g4_hh_average_income_source_a_income_farming, 0) > 0,
        TRUE, FALSE, missing = FALSE
      )
    )
  
  # --- WHOLE POPULATION PIE ---
  df_full <- df_year %>%
    mutate(
      group = if_else(is_fisher, "Fishers", "Non-Fishers")
    ) %>%
    count(group) %>%
    mutate(
      prop = n / sum(n),
      label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
    )
  
  n_total <- sum(df_full$n)
  
  pie1 <- ggplot(df_full, aes(x = "", y = prop, fill = group)) +
    geom_col(width = 1, color = "white") +
    coord_polar(theta = "y") +
    geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 5) +
    scale_fill_manual(values = c("Fishers" = "#6baed6", "Non-Fishers" = "#fb6a4a")) +
    labs(title = paste0("Whole Population in ", yr, " (n = ", n_total, ")")) +
    theme_void() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
      legend.position = "none"
    )
  
  # --- FISHING POPULATION PIE ---
  df_fishers <- df_year %>%
    filter(is_fisher) %>%
    mutate(
      group = if_else(is_farmer, "Fishers who also farm", "Fishers only")
    ) %>%
    count(group) %>%
    mutate(
      prop = n / sum(n),
      label = paste0(group, "\n", scales::percent(prop, accuracy = 1))
    )
  
  n_fishers <- sum(df_fishers$n)
  
  pie2 <- ggplot(df_fishers, aes(x = "", y = prop, fill = group)) +
    geom_col(width = 1, color = "white") +
    coord_polar(theta = "y") +
    geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 4) +
    scale_fill_manual(values = c("Fishers only" = "#6baed6", "Fishers who also farm" = "#B2DF8A")) +
    labs(title = paste0("Fishing Population (n = ", n_fishers, ")")) +
    theme_void() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
      legend.position = "none"
    )
  
  # Combine and display
  final_plot <- ggdraw() +
    draw_plot(pie1, x = -0.2, y = 0, width = 1, height = 1) +
    draw_plot(pie2, x = 0.44, y = 0.1, width = 0.6, height = 0.6)
  
  print(final_plot)
}